package com.orifine.dao;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import com.orifine.dao.annotation.Delete;
import com.orifine.dao.annotation.Insert;
import com.orifine.dao.annotation.Invoke;
import com.orifine.dao.annotation.Param;
import com.orifine.dao.annotation.Select;
import com.orifine.dao.annotation.Update;


public class DaoModel {
	private DaoModelType modelType = DaoModelType.NULL;
	private Method daoMethod;
	private Method mapperMethod;
	private Select selectAnnotation = null;
	private Insert insertAnnotation = null;
	private Update updateAnnotation = null;
	private Delete deleteAnnotation = null;
	private Invoke invokeAnnotation = null;
	
	public DaoModelType getType() {
		return modelType;
	}

	public Method getDaoMethod() {
		return daoMethod;
	}

	public Method getMapperMethod() {
		return mapperMethod;
	}

	public DaoModel(Method daoMethod, Method mapperMethod) {
		this.daoMethod = daoMethod;
		this.mapperMethod = mapperMethod;
		
		this.selectAnnotation = daoMethod.getAnnotation(Select.class);
		this.insertAnnotation = daoMethod.getAnnotation(Insert.class);
		this.updateAnnotation = daoMethod.getAnnotation(Update.class);
		this.deleteAnnotation = daoMethod.getAnnotation(Delete.class);
		this.invokeAnnotation = daoMethod.getAnnotation(Invoke.class);
		
		if(selectAnnotation != null){
			if(modelType == DaoModelType.NULL) {
				modelType = DaoModelType.SELECT;
			} else {
				throw new RuntimeException(Select.class+"、"+Insert.class+"、"+Update.class+"、"+Delete.class+"注解在"+daoMethod+"上只能单一使用");
			}
		}
		
		if(insertAnnotation != null){
			if(modelType == DaoModelType.NULL) {
				modelType = DaoModelType.INSERT;
			} else {
				throw new RuntimeException(Select.class+"、"+Insert.class+"、"+Update.class+"、"+Delete.class+"注解在"+daoMethod+"上只能单一使用");
			}
		}
		
		if(updateAnnotation != null){
			if(modelType == DaoModelType.NULL) {
				modelType = DaoModelType.UPDATE;
			} else {
				throw new RuntimeException(Select.class+"、"+Insert.class+"、"+Update.class+"、"+Delete.class+"注解在"+daoMethod+"上只能单一使用");
			}
		}
		
		if(deleteAnnotation != null){
			if(modelType == DaoModelType.NULL) {
				modelType = DaoModelType.DELETE;
			} else {
				throw new RuntimeException(Select.class+"、"+Insert.class+"、"+Update.class+"、"+Delete.class+"注解在"+daoMethod+"上只能单一使用");
			}
		}
		
		if(invokeAnnotation != null){
			if(modelType == DaoModelType.NULL) {
				modelType = DaoModelType.INVOKE;
			}
		}
		
		if(modelType == DaoModelType.NULL){
			//没有找到可识别的DAO SQL类型
			return;
		}
	}
	
	public String getValue(){
		switch(modelType){
		case SELECT:
			return selectAnnotation.value();
		case DELETE:
			return deleteAnnotation.value();
		case UPDATE:
			return updateAnnotation.value();
		case INSERT:
			return insertAnnotation.value();
		default:
			throw new RuntimeException("getValue exceiption");
		}
	}
	
	public Map<String, Object> getDirectory(Object[] args){
		Map<String, Object> directory = new HashMap<String, Object>();
		for(int i=0; i < args.length; i++){
			Param param = getParamAnnotation(daoMethod, i);
			if(param != null){
				directory.put(param.value(), args[i]);
			}
			
			param = getParamAnnotation(mapperMethod, i);
			if(param != null){
				directory.put(param.value(), args[i]);
			}
		}
		return directory;
	}
	
	private Param getParamAnnotation(Method method, int paramIndex){
		for(Annotation annotation : method.getParameterAnnotations()[paramIndex]){
			if(annotation instanceof Param){
				return (Param)annotation;
			}
		}
		return null;
	}
}
